//
//  UIScrollView.swift
//  Documentation
//
//  Created by Toj on 11/18/22.
//
//  UIScrollView
//

open class UIScrollView : UIView, NSCoding, UIFocusItemScrollableContainer {
    
    weak open var delegate: UIScrollViewDelegate?
    
    // 内容视图的原点与滚动视图原点的偏移点, 默认值: .zero
    open var contentOffset: CGPoint = .zero
    
    // 内容视图的大小, 默认值: .zero
    open var contentSize: CGSize = .zero
    
    // 在内容周围添加额外的滚动区域, 默认值: .zero.
    open var contentInset: UIEdgeInsets = .zero
    
    // 拖动时尝试锁定垂直或水平滚动. 默认值: NO
    open var isDirectionalLockEnabled: Bool = false
    
    // 弹过内容的边缘, 是否回弹. 默认值: true
    open var bounces: Bool = true
    
    // 如果YES and bounces是YES, 即使内容小于边界, 也允许垂直拖动. 默认值: false
    open var alwaysBounceVertical: Bool = false
    
    // 如果YES and bounces是YES，即使内容小于边界，也允许水平拖动. 默认值: false
    open var alwaysBounceHorizontal: Bool = false
    
    // 表示滚动试图是否启用分页. 默认值: NO
    open var isPagingEnabled: Bool = false
    
    // 是否可以拖拽(滚动). 默认值: true
    open var isScrollEnabled: Bool = true
    
    // 垂直滚动条(指示器)是否可见. 默认值: true
    open var showsVerticalScrollIndicator: Bool = true
    
    // 水平滚动条(指示器)是否可见. 默认值: true
    open var showsHorizontalScrollIndicator: Bool = true
    
    // default is UIScrollViewIndicatorStyleDefault
    // 滚动条(指示器)的样式
    open var indicatorStyle: UIScrollView.IndicatorStyle = .default
    
    // 只使用setter, 方便将垂直scrollindicatorinsets和水平scrollindicatorinsets设置为相同的值.
    // 如果这些属性被设置为不同的值， 则该getter(已弃用)的返回值是未定义的.
    // 滚动条(指示器)从滚动视图边缘插入的距离
    open var scrollIndicatorInsets: UIEdgeInsets
    
    // 表示用户抬起手指后的减速率
    open var decelerationRate: UIScrollView.DecelerationRate
    
    // 滑动时索引展现方式
    open var indexDisplayMode: UIScrollView.IndexDisplayMode
    
    // animate at constant velocity to new offset
    open func setContentOffset(_ contentOffset: CGPoint, animated: Bool)
    
    // 滚动内容的特定区域
    open func scrollRectToVisible(_ rect: CGRect, animated: Bool)
    
    // 暂时显示滚动条(指示器)
    open func flashScrollIndicators()
    
    
    // 如果用户触摸过，返回YES。可能还没有开始拖
    open var isTracking: Bool { get }
    
    // 如果用户已经开始滚动，返回YES。这可能需要一些时间和或距离来启动拖拽
    open var isDragging: Bool { get }
    
    // 如果用户没有拖动(触摸)但滚动视图仍在移动，则返回YES
    open var isDecelerating: Bool { get }
    
    // 默认为YES.
    // 表示滚动视图是否延迟对触摸手势的处理
    // 如果NO, 我们立即调用-touchesShouldBegin:withEvent:inContentView:.
    open var delaysContentTouches: Bool
    
    // 默认为YES.
    // 这个值表示内容视图中的触摸是否始终导致跟踪
    // 如果NO, 那么一旦我们开始跟踪, 如果触摸移动, 我们就不会尝试拖动.
    open var canCancelContentTouches: Bool
    
    // 通过子类重写手指触碰屏幕内容的默认行为
    // 覆盖子类的点, 以控制触摸事件传递到滚动视图的子视图
    // 在触摸被传递到滚动视图的子视图之前调用.
    // 如果它返回NO, 触摸将不会被传递到子视图
    // 默认为YES.
    open func touchesShouldBegin(_ touches: Set<UITouch>, with event: UIEvent?, in view: UIView) -> Bool
    
    
    // 返回是否取消与内容子视图相关的触摸并开始拖动.
    // 在滚动开始之前调用, 如果触摸已经传递给滚动视图的子视图.
    // 如果它返回NO, 触摸将继续传递到子视图, 并且不会发生滚动
    // 如果cancancelcontenttouchsno则不调用.
    // 如果视图不是UIControl,
    // 默认返回true
    open func touchesShouldCancel(in view: UIView) -> Bool = true
    
    
    
    // 一个浮点值, 指定应用于滚动视图内容的当前缩放因子最小值. 默认值: 1.0
    open var minimumZoomScale: CGFloat = 1.0
    // 一个浮点值, 指定应用于滚动视图内容的当前缩放因子最大值. 默认值: 1.0
    // 必须大于 minimumZoomScale
    open var maximumZoomScale: CGFloat = 1.0
    
    // 一个浮点值, 指定应用于滚动视图内容的当前缩放因子. 默认值: 1.0
    open var zoomScale: CGFloat = 1.0
    // 一个浮点值, 指定应用于滚动视图内容的当前缩放因子, 是否有动画过程. 默认值: 1.0
    open func setZoomScale(_ scale: CGFloat, animated: Bool)
    
    // 缩放内容的特定区域
    open func zoom(to rect: CGRect, animated: Bool)
    
    // 默认为true. 如果设置了, 用户可以在手势时超过最小/最大缩放, 并且在手势结束时缩放会动画到最小/最大值
    // 当缩放超过最大或最小限制时, 确定滚动视图是对内容缩放进行动画处理
    // 换言之 缩放超过最大/ 最小值, 回弹到最大/ 最小值
    open var bouncesZoom: Bool = true
    
    // 当前内容视图正在缩放
    open var isZooming: Bool { get }
    // 如果我们正在缩放到最小/最大值，则返回YES
    open var isZoomBouncing: Bool { get }
    
    // 当用户点击状态栏时, 触摸下方最靠近状态栏的滚动视图将被滚动到顶部,
    // 但只有当它的' scrollsToTop '属性为YES时, 它的委托不会从' -scrollViewShouldScrollToTop: '返回NO, 并且它还没有在顶部.
    // 在iPhone上, 只有当屏幕上有一个滚动视图' scrollsToTop ' == YES时, 我们才执行此手势. 如果找到多个, 则不会滚动.
    open var scrollsToTop: Bool = true
    
    
    // 平移手势的底层手势识别器
    // 使用这些访问器来配置滚动视图的内置手势识别器
    // 不更改手势的委托或覆盖这些属性的getter
    // 修改' panGestureRecognizer. '允许touchtypes限制滚动到特定的触摸类型集合
    open var panGestureRecognizer: UIPanGestureRecognizer { get }
    
    // 缩放手势的底层手势识别器
    // 禁用缩放时, 将返回nil.
    open var pinchGestureRecognizer: UIPinchGestureRecognizer? { get }
    
    // 底层手势识别用于定向按钮按压
    // 在默认情况下是禁用的， 但可以启用在直接按下上/下/左/右箭头键时执行滚动, 而不是在响应焦点更新时间接滚动.
    open var directionalPressGestureRecognizer: UIGestureRecognizer { get }
    
    
    // 在滚动开始时关闭键盘的一种行为，就是选择一种关闭键盘的方法
    open var keyboardDismissMode: UIScrollView.KeyboardDismissMode
    
    // 与滚动试图关联的刷新控件
    open var refreshControl: UIRefreshControl?
    
    
    
    // MARK: - iOS 11.0 Start
    @available(iOS 11.0, *)
    
    /* 用来确认系统的偏移的行为
     * iOS 11废弃 vc.automaticallyAdjustsScrollViewInsets
     * contentInsetAdjustmentBehavior代替 automaticallyAdjustsScrollViewInsets
     * 可以使用: UIScrollView.appearance().contentInsetAdjustmentBehavior = .never, 统一设置
     * 详细请看 UIScrollViewEnum.ContentInsetAdjustmentBehavior
     */
    open var contentInsetAdjustmentBehavior: UIScrollView.ContentInsetAdjustmentBehavior
    
    /*
     * 从内容插图派生的插图和滚动视图的安全区域.
     
     * 使用此属性可获得绘制内容的调整区域.
     * contentInsetAdjustmentBehavior 属性确定是否在调整中包含安全区域插入.
     * 然后将安全区嵌入添加到 contentInset 属性中的值, 以获得该属性的最终值.
     * . 未使用过
     */
    open var adjustedContentInset: UIEdgeInsets { get }
    
    /* 当滚动视图的调整后的内容插图发生更改时调用. 未使用过 */
    open func adjustedContentInsetDidChange()
    
    /* 基于滚动视图的未变换框架矩形的布局参照物. 未使用过 */
    open var contentLayoutGuide: UILayoutGuide { get }
    
    /* 基于滚动视图的未变换内容矩形的布局参照物. 未使用过 */
    open var frameLayoutGuide: UILayoutGuide { get }
    
    // MARK: - iOS 11.0 End
    
    // MARK: - iOS 11.1 Start
    
    // 默认是: zero. 从滚动视图的边缘插入滚动指示器的垂直距离
    open var verticalScrollIndicatorInsets: UIEdgeInsets
    // 默认是: zero. 从滚动视图的边缘插入滚动指示器的水平距离
    open var horizontalScrollIndicatorInsets: UIEdgeInsets
    
    // MARK: - iOS 11.1 End
    
    // MARK: - iOS 13.0 Start
    @available(iOS 13.0, *)
    
    /* 设置系统是否自动调整滚动指示器的插图.
     * 默认值: true.
     * 会导致适配iPhoneX 时设置了偏移量的滚动条偏移两倍
     * 处理方案: 设置为false
     */
    open var automaticallyAdjustsScrollIndicatorInsets: Bool = true
    
    // MARK: - iOS 13.0 End
}
